package com.moss.cloud.common.security.filter;

import com.alibaba.fastjson2.JSON;
import com.moss.cloud.auth.api.service.IGeneralSecurityService;
import com.moss.cloud.common.core.custom.CustomHttpHeaders;
import com.moss.cloud.common.core.custom.CustomRequestWrapper;
import com.moss.cloud.common.core.exception.SystemErrorType;
import com.moss.cloud.common.core.model.Result;
import com.moss.cloud.common.core.utils.BooleanHandel;
import com.moss.cloud.common.security.permission.IAuthService;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 自定义业务过滤器
 *
 * @author 瑾年
 * @date 2023年5月25日
 */

@Slf4j
@Order(1)
@Configuration
@ComponentScan(basePackages = {
        "com.moss.cloud.auth.api",
        "com.moss.cloud.common.security.permission"
})
public class PermissionSecurity implements Filter {

    private final IAuthService authService;
    private final IGeneralSecurityService generalSecurityService;

    public PermissionSecurity(IAuthService authService, IGeneralSecurityService generalSecurityService) {
        this.authService = authService;
        this.generalSecurityService = generalSecurityService;
    }


    @SneakyThrows
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) {
        log.info("权限安全验证");
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        String authentication = request.getHeader(CustomHttpHeaders.X_CLIENT_TOKEN_USER);
        String method = request.getMethod();
        String url = request.getRequestURI();
        //不需要签权的url
        if (generalSecurityService.ignoreAuthentication(url)) {
            log.info("不需要鉴权URL:{},method:{}", url, method);
            chain.doFilter(this.addRequestHeader(request, authentication), servletResponse);
            return;
        }
        // 进行权限检验
        if (authService.hasPermission(authentication, url, method)) {
            log.info("安全验证通过重新转发请求URL:{},method:{}", url, method);
            chain.doFilter(this.addRequestHeader(request, authentication), servletResponse);
        } else {
            HttpServletResponse response = (HttpServletResponse) servletResponse;
            Result<?> result = Result.fail(SystemErrorType.UNAUTHORIZED, "");
            String jsonString = JSON.toJSONString(result);
            ServletOutputStream outputStream = response.getOutputStream();
            outputStream.write(jsonString.getBytes());
            outputStream.flush();
        }

    }

    /**
     * 自定义请求头
     *
     * @param request        HttpServletRequest
     * @param authentication 认证信息
     * @return CustomRequestWrapper
     */
    private CustomRequestWrapper addRequestHeader(HttpServletRequest request, String authentication) {
        CustomRequestWrapper customRequestWrapper = new CustomRequestWrapper(request);
        BooleanHandel.isTrue(StringUtils.isNotBlank(authentication)).trueHandle(() -> {
            //将jwt token中的用户信息传给服务
            customRequestWrapper.addHeader(CustomHttpHeaders.X_CLIENT_TOKEN_USER, authentication);
            customRequestWrapper.addHeader(CustomHttpHeaders.X_FORWARDED_FOR, request.getHeader(CustomHttpHeaders.X_FORWARDED_FOR));
            customRequestWrapper.addHeader(CustomHttpHeaders.CONTENT_TYPE, request.getHeader(CustomHttpHeaders.CONTENT_TYPE));
        });
        return customRequestWrapper;
    }
}
